﻿// -----------------------------------------------------------------------
// <copyright file="PopularBookFilter.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Domain.Filters
{
	#region Usings

	using System;
	using System.Linq;
	using System.Linq.Expressions;

	using MBOP.Core.Entities.Library;
	using MBOP.Core.FilterContexts;
	using MBOP.Core.Interfaces.Common;

	#endregion

	/// <summary>
	/// Provides filtering condition for popular books.
	/// </summary>
	public class PopularBookFilter : IFilter<Book>
	{
		#region PrivateFields

		/// <summary>
		/// Represents the  filter context.
		/// </summary>
		private BookFilterContext _filterContext;

		/// <summary>
		/// Represents the filter condition.
		/// </summary>
		private Expression<Func<Book, bool>> _filterCondition;

		#endregion

		#region Contructors

		/// <summary>
		/// Initializes a new instance of the <see cref="PopularBookFilter"/> class.
		/// </summary>
		/// <param name="filterContext">The filter context.</param>
		public PopularBookFilter(BookFilterContext filterContext)
		{
			this._filterContext = filterContext;
		}

		#endregion

		#region IFilter<Book> Implementation

		/// <summary>
		/// Gets the filter condition.
		/// </summary>
		public Expression<Func<Book, bool>> FilterCondition
		{
			get
			{
				if (this._filterCondition == null)
				{
					this._filterCondition =
						book =>
						book.Subscriptions
							.GroupBy(selector => selector.SubscriptionSet)
							.Select(group => group.OrderByDescending(groupEl => groupEl.ID).FirstOrDefault())
							.Where(
							subscription => subscription.State == (int) SubscribeState.Waiting).Count() >= this._filterContext.FiltersConfig.PopularFilter.HistoryOrQueueCount
						||
						book.Subscriptions
							.GroupBy(selector => selector.SubscriptionSet)
							.Select(group => group.OrderByDescending(groupEl => groupEl.ID).FirstOrDefault())
							.Where(subscription => subscription.State == (int) SubscribeState.History).Count() >= this._filterContext.FiltersConfig.PopularFilter.HistoryOrQueueCount;
				}

				return this._filterCondition;
			}
		}

		#endregion
	}
}
